From: Christian Hergert Date: Fri, 7 Jan 2022 00:30:34 +0000 (-0800) Subject: textview: remove drag selection after dnd move action X-Git-Tag: archive/raspbian/4.6.5+ds-1+rpi1~1^2~61^2^2~111^2 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=e14d6fe9d5398b0e0edc82ffece1f1726445758a;p=gtk4.git textview: remove drag selection after dnd move action If we have a GDK_ACTION_MOVE, we need to delete the selection. However, previously this only worked when the drop target and drag source were different applications, as the selection would get messed up along the way. Instead, we stash marks for the duration of the operation so that we can delete the appropriate selection when completing the move. --- diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c index db23e9ad86..44fd7c7576 100644 --- a/gtk/gtktextview.c +++ b/gtk/gtktextview.c @@ -231,8 +231,13 @@ struct _GtkTextViewPrivate guint first_validate_idle; /* Idle to revalidate onscreen portion, runs before resize */ guint incremental_validate_idle; /* Idle to revalidate offscreen portions, runs after redraw */ + /* Mark for drop target */ GtkTextMark *dnd_mark; + /* Mark for selection of drag source */ + GtkTextMark *dnd_drag_begin_mark; + GtkTextMark *dnd_drag_end_mark; + GtkIMContext *im_context; GtkWidget *popup_menu; GMenuModel *extra_menu; @@ -8056,8 +8061,26 @@ static void dnd_finished_cb (GdkDrag *drag, GtkTextView *self) { - if (gdk_drag_get_selected_action (drag) == GDK_ACTION_MOVE) - gtk_text_buffer_delete_selection (self->priv->buffer, TRUE, self->priv->editable); + GtkTextBuffer *buffer = self->priv->buffer; + + if (self->priv->dnd_drag_begin_mark) + { + if (gdk_drag_get_selected_action (drag) == GDK_ACTION_MOVE) + { + { + GtkTextIter begin, end; + + gtk_text_buffer_get_iter_at_mark (buffer, &begin, self->priv->dnd_drag_begin_mark); + gtk_text_buffer_get_iter_at_mark (buffer, &end, self->priv->dnd_drag_end_mark); + gtk_text_buffer_delete (buffer, &begin, &end); + } + } + + gtk_text_buffer_delete_mark (buffer, self->priv->dnd_drag_begin_mark); + gtk_text_buffer_delete_mark (buffer, self->priv->dnd_drag_end_mark); + self->priv->dnd_drag_begin_mark = NULL; + self->priv->dnd_drag_end_mark = NULL; + } self->priv->drag = NULL; } @@ -8067,6 +8090,16 @@ dnd_cancel_cb (GdkDrag *drag, GdkDragCancelReason reason, GtkTextView *self) { + GtkTextBuffer *buffer = self->priv->buffer; + + if (self->priv->dnd_drag_begin_mark) + { + gtk_text_buffer_delete_mark (buffer, self->priv->dnd_drag_begin_mark); + gtk_text_buffer_delete_mark (buffer, self->priv->dnd_drag_end_mark); + self->priv->dnd_drag_begin_mark = NULL; + self->priv->dnd_drag_end_mark = NULL; + } + self->priv->drag = NULL; } @@ -8108,6 +8141,9 @@ gtk_text_view_start_selection_dnd (GtkTextView *text_view, paintable = gtk_text_util_create_rich_drag_icon (widget, buffer, &start, &end); gtk_drag_icon_set_from_paintable (drag, paintable, 0, 0); g_object_unref (paintable); + + text_view->priv->dnd_drag_begin_mark = gtk_text_buffer_create_mark (buffer, NULL, &start, TRUE); + text_view->priv->dnd_drag_end_mark = gtk_text_buffer_create_mark (buffer, NULL, &end, TRUE); } text_view->priv->drag = drag;